#include <p18f25k20.h>
#include <stdlib.h>
#include <string.h>
#include "Initializations.h"
#include "Delays.h"
#include "Nokia_LCD_controls.h"
#include "globals.h"
#include "System_Functions.h"
#include "Debug_Menu.h"




/* Debug Menu global variables */
unsigned char state = 0;
unsigned char contrast_ones = 0;
unsigned char contrast_tens = 0;
unsigned char contrast_hundreds = 0;
unsigned char backlight_ones = 0;
unsigned char backlight_tens = 0;
unsigned char backlight_hundreds = 0;
unsigned char backlight_seconds = 0;
unsigned char filter_minutes_ones = 0;
unsigned char filter_minutes_tens = 0;
unsigned char filter_minutes_hundreds = 0;
unsigned char filter_minutes_thousands = 0;






void debug_menu(void)
{

//    unsigned char backlight_count_temp = 0;
//
//    //save the current backlight time, and set the backlight
//    // to never go off, while it's in this menu
//    backlight_count_temp = backlight_seconds_count;
//    backlight_seconds_count = 255;


    state = 0;

    backlight_seconds = backlight_seconds_count;

    while(TIME_SET_SW)
    {

        LCD_clear();

        LCD_write(LCD_COMMAND, LCD_YADDR(0));
        LCD_write(LCD_COMMAND, LCD_XADDR(0));

        LCD_string("Debug Menu:");

        if(state == 8)
        {
            state = 0;
        }


        switch(state)
        {
            case 3:
                LCD_invert_menu();
                break;

            case 7:
                LCD_all_pixels_on_menu();
                break;

            case 2:
                LCD_contrast_menu();
                break;

            case 4:
                LCD_bias_system_menu();
                break;

            case 1:
                LCD_backlight_menu();
                break;

            case 5:
                LCD_tempco_menu();
                break;

            case 6:
                LEDs_test_menu();
                break;

            case 0:
                Filter_minutes_display();
                break;

            default:
                break;


        } //end switch(state)






    } //end while(TIME_SET_SW)



    milliseconds(DEBOUNCE_TIME);   //Debounce the switch
    while(!TIME_SET_SW);  //Wait until the button is realeased

//    //restore the proper backlight time, and make sure the
//    // counter is properly set
//    backlight_seconds_count = backlight_count_temp;
//    backlight_seconds_counter = backlight_seconds_count;

    LCD_clear();
    parse_time_minutes();
    update_clock(1);        //with the frame
    update_runtime_mins();
    update_start_time();
    


    
    

    return;
}




void LCD_invert_menu(void)
{
    LCD_write(LCD_COMMAND, LCD_YADDR(1));
    LCD_write(LCD_COMMAND, LCD_XADDR(0));
    LCD_string("LCD Display");

    LCD_write(LCD_COMMAND, LCD_YADDR(3));
    LCD_write(LCD_COMMAND, LCD_XADDR(4));
    

    if(LCD_invert)
    {
        LCD_string("Invert LCD");
    }
    else
    {
        LCD_string("Set to Normal");
    }

    //If either of these buttons are pressed, exit
    //  out of this loop, back to the main loop.
    //There, if TIME_SET_SW has been pressed, then
    //  that main loop will also exit
    while(TIME_SET_SW && START_SET_SW)
    {

                if(!SW_P)
                {
                    milliseconds(DEBOUNCE_TIME);
                    while(!SW_P);
                    LCD_invert = 1;
                   if(LCD_invert == 1)
                    {
                         LCD_clear_row(3);
                         LCD_write(LCD_COMMAND, LCD_YADDR(3));
                         LCD_write(LCD_COMMAND, LCD_XADDR(4));
                         LCD_string("Invert LCD");
                    }
                    else
                    {
                         LCD_clear_row(3);
                         LCD_write(LCD_COMMAND, LCD_YADDR(3));
                         LCD_write(LCD_COMMAND, LCD_XADDR(4));
                         LCD_string("Set to Normal");
                    }

                }

                if(!SW_M)
                {
                    milliseconds(DEBOUNCE_TIME);
                    while(!SW_M);
                    LCD_invert = 0;

                    if(LCD_invert == 1)
                    {
                         LCD_clear_row(3);
                         LCD_write(LCD_COMMAND, LCD_YADDR(3));
                         LCD_write(LCD_COMMAND, LCD_XADDR(4));
                         LCD_string("Invert LCD");
                    }
                    else
                    {
                         LCD_clear_row(3);
                         LCD_write(LCD_COMMAND, LCD_YADDR(3));
                         LCD_write(LCD_COMMAND, LCD_XADDR(4));
                         LCD_string("Set to Normal");
                    }

                }

                //When the manual switch is pressed, then write the
                // desired data to the LCD
                if(!MANUAL_SW)
                {
                    milliseconds(DEBOUNCE_TIME);   //Debounce the switch
                    while(!MANUAL_SW);  //Wait until the button is realeased


                    LCD_write(LCD_COMMAND, 0x20);   //Tell the LCD that regular commands follow
                    
                    if(LCD_invert == 1)
                    {
                        LCD_write(LCD_COMMAND, 0x0D);   //Set display control
                                                        // 0x0C = normal mode
                                                        // 0x0D = inverse mode
                                                        // 0x09 = all pixels on
                    }
                    else
                    {
                        LCD_write(LCD_COMMAND, 0x0C);   //Set display control
                                                        // 0x0C = normal mode
                                                        // 0x0D = inverse mode
                                                        // 0x09 = all pixels on
                    }

                    EEPROM_write_with_check(LCD_INVERT_ADDR, LCD_invert);

                }

    }

    while(!START_SET_SW);   //If this button was pressed, then wait for it to be released

    state++;        //move to the next state

    return;
}





void LCD_all_pixels_on_menu(void)
{
    LCD_write(LCD_COMMAND, LCD_YADDR(1));
    LCD_write(LCD_COMMAND, LCD_XADDR(0));
    LCD_string("LCD Pixels");

    LCD_write(LCD_COMMAND, LCD_YADDR(3));
    LCD_write(LCD_COMMAND, LCD_XADDR(4));
    LCD_string("Turn all on");

    LCD_write(LCD_COMMAND, LCD_YADDR(4));
    LCD_write(LCD_COMMAND, LCD_XADDR(4));
    LCD_string("(for 5 seconds)");

    //If either of these buttons are pressed, exit
    //  out of this loop, back to the main loop.
    //There, if TIME_SET_SW has been pressed, then
    //  that main loop will also exit
    while(TIME_SET_SW && START_SET_SW)
    {
                //When the manual switch is pressed, then write the
                // desired data to the LCD
                if(!MANUAL_SW)
                {
                    milliseconds(DEBOUNCE_TIME);   //Debounce the switch
                    while(!MANUAL_SW);  //Wait until the button is realeased


                    LCD_write(LCD_COMMAND, 0x20);   //Tell the LCD that regular commands follow

                    
                    LCD_write(LCD_COMMAND, 0x09);   //Set display control
                                                    // 0x0C = normal mode
                                                    // 0x0D = inverse mode
                                                    // 0x09 = all pixels on

                    milliseconds(5000);

                    if(LCD_invert)
                    {
                        LCD_write(LCD_COMMAND, 0x0D);   //Set display control
                                                        // 0x0C = normal mode
                                                        // 0x0D = inverse mode
                                                        // 0x09 = all pixels on
                    }
                    else
                    {
                        LCD_write(LCD_COMMAND, 0x0C);   //Set display control
                                                        // 0x0C = normal mode
                                                        // 0x0D = inverse mode
                                                        // 0x09 = all pixels on
                    }

                }

    }

    while(!START_SET_SW);   //If this button was pressed, then wait for it to be released

    
    state++;        //move to the next state

    return;
}




void LEDs_test_menu(void)
{
    LCD_write(LCD_COMMAND, LCD_YADDR(1));
    LCD_write(LCD_COMMAND, LCD_XADDR(0));
    LCD_string("LEDs Test");

    LCD_write(LCD_COMMAND, LCD_YADDR(3));
    LCD_write(LCD_COMMAND, LCD_XADDR(4));
    LCD_string("Turn all on");

    LCD_write(LCD_COMMAND, LCD_YADDR(4));
    LCD_write(LCD_COMMAND, LCD_XADDR(4));
    LCD_string("(for 3 seconds)");

    //If either of these buttons are pressed, exit
    //  out of this loop, back to the main loop.
    //There, if TIME_SET_SW has been pressed, then
    //  that main loop will also exit
    while(TIME_SET_SW && START_SET_SW)
    {
                //When the manual switch is pressed, then write the
                // desired data to the LCD
                if(!MANUAL_SW)
                {
                    milliseconds(DEBOUNCE_TIME);   //Debounce the switch
                    while(!MANUAL_SW);  //Wait until the button is realeased


                    GREEN_LEDS = 1;
                    RED_LEDS = 1;
                    YELLOW_LEDS = 1;

                    milliseconds(3000);

                    GREEN_LEDS = 0;
                    RED_LEDS = 0;
                    YELLOW_LEDS = 0;


                }

    }

    while(!START_SET_SW);   //If this button was pressed, then wait for it to be released


    state++;        //move to the next state

    return;
}





void LCD_contrast_menu(void)
{
    
    LCD_write(LCD_COMMAND, LCD_YADDR(1));
    LCD_write(LCD_COMMAND, LCD_XADDR(0));
    LCD_string("LCD Contrast");

    display_contrast();
    

    //If either of these buttons are pressed, exit
    //  out of this loop, back to the main loop.
    //There, if TIME_SET_SW has been pressed, then
    //  that main loop will also exit
    while(TIME_SET_SW && START_SET_SW)
    {
                if(!SW_P)
                {
                    milliseconds(DEBOUNCE_TIME);
                    while(!SW_P);
                    LCD_contrast++;

                    display_contrast();
                }

                if(!SW_M)
                {
                    milliseconds(DEBOUNCE_TIME);
                    while(!SW_M);
                    LCD_contrast--;

                    display_contrast();
                }

                //When the manual switch is pressed, then write the
                // desired data to the LCD
                if(!MANUAL_SW)
                {
                    milliseconds(DEBOUNCE_TIME);   //Debounce the switch
                    while(!MANUAL_SW);  //Wait until the button is realeased


                    LCD_write(LCD_COMMAND, 0x21);   //Tell the LCD that extended commands follow
                    milliseconds(5);
                    
                    LCD_write(LCD_COMMAND, (LCD_contrast | 0x80));

                    milliseconds(5);
                    LCD_write(LCD_COMMAND, 0x20);   //Tell the LCD that regular commands follow
                                                    //  Set this back to normal
                    milliseconds(5);


                    EEPROM_write_with_check(LCD_CONTRAST_ADDR, LCD_contrast);


                }

    }

    while(!START_SET_SW);   //If this button was pressed, then wait for it to be released

    state++;        //move to the next state

    return;
}




void display_contrast(void)
{
    unsigned char temp = 0;

    contrast_hundreds = LCD_contrast / 100;
    temp = LCD_contrast - (contrast_hundreds * 100);
    contrast_tens = temp / 10;
    contrast_ones = temp - (contrast_tens * 10);

    LCD_clear_row(3);

    LCD_write(LCD_COMMAND, LCD_YADDR(3));
    LCD_write(LCD_COMMAND, LCD_XADDR(4));

    LCD_char(contrast_hundreds+48);
    LCD_char(contrast_tens+48);
    LCD_char(contrast_ones+48);

    return;
}





void LCD_bias_system_menu(void)
{

    LCD_write(LCD_COMMAND, LCD_YADDR(1));
    LCD_write(LCD_COMMAND, LCD_XADDR(0));
    LCD_string("LCD Bias System");

    LCD_write(LCD_COMMAND, LCD_YADDR(3));
    LCD_write(LCD_COMMAND, LCD_XADDR(4));

    LCD_char(LCD_bias_system + 48);


    //If either of these buttons are pressed, exit
    //  out of this loop, back to the main loop.
    //There, if TIME_SET_SW has been pressed, then
    //  that main loop will also exit
    while(TIME_SET_SW && START_SET_SW)
    {

        if(LCD_bias_system == 8)
        {
            LCD_bias_system = 0;
        }

                if(!SW_P)
                {
                    milliseconds(DEBOUNCE_TIME);
                    while(!SW_P);
                    LCD_bias_system++;

                    LCD_write(LCD_COMMAND, LCD_YADDR(3));
                    LCD_write(LCD_COMMAND, LCD_XADDR(4));
                    LCD_char(LCD_bias_system + 48);
                }

                if(!SW_M)
                {
                    milliseconds(DEBOUNCE_TIME);
                    while(!SW_M);
                    LCD_bias_system--;

                    LCD_write(LCD_COMMAND, LCD_YADDR(3));
                    LCD_write(LCD_COMMAND, LCD_XADDR(4));
                    LCD_char(LCD_bias_system + 48);
                }

                //When the manual switch is pressed, then write the
                // desired data to the LCD
                if(!MANUAL_SW)
                {
                    milliseconds(DEBOUNCE_TIME);   //Debounce the switch
                    while(!MANUAL_SW);  //Wait until the button is realeased


                    LCD_write(LCD_COMMAND, 0x21);   //Tell the LCD that extended commands follow
                    milliseconds(5);

                    LCD_write(LCD_COMMAND, (LCD_bias_system | 0x10));

                    milliseconds(5);
                    LCD_write(LCD_COMMAND, 0x20);   //Tell the LCD that regular commands follow
                                                    //  Set this back to normal
                    milliseconds(5);

                    EEPROM_write_with_check(LCD_BIAS_SYSTEM_ADDR, LCD_bias_system);

                }

    }

    while(!START_SET_SW);   //If this button was pressed, then wait for it to be released

    state++;        //move to the next state

    return;
}




void LCD_backlight_menu(void)
{

    LCD_write(LCD_COMMAND, LCD_YADDR(1));
    LCD_write(LCD_COMMAND, LCD_XADDR(0));
    LCD_string("LCD Backlight");

    LCD_write(LCD_COMMAND, LCD_YADDR(3));
    LCD_write(LCD_COMMAND, LCD_XADDR(4));

    LCD_string("Seconds:  ");

    display_backlight_time();


    //If either of these buttons are pressed, exit
    //  out of this loop, back to the main loop.
    //There, if TIME_SET_SW has been pressed, then
    //  that main loop will also exit
    while(TIME_SET_SW && START_SET_SW)
    {
                if(!SW_P)
                {
                    milliseconds(DEBOUNCE_TIME);
                    while(!SW_P);
                    backlight_seconds++;

                    display_backlight_time();
                }

                if(!SW_M)
                {
                    milliseconds(DEBOUNCE_TIME);
                    while(!SW_M);
                    backlight_seconds--;

                    display_backlight_time();
                }

                //When the manual switch is pressed, then write the
                // desired data to the LCD
                if(!MANUAL_SW)
                {
                    backlight_seconds_count = backlight_seconds;
                    EEPROM_write_with_check(LCD_BACKLIGHT_TIME_ADDR, backlight_seconds);
                }

    }

    while(!START_SET_SW);   //If this button was pressed, then wait for it to be released

    state++;        //move to the next state

    return;
}



void display_backlight_time(void)
{
    unsigned char temp = 0;

    backlight_hundreds = backlight_seconds / 100;
    temp = backlight_seconds - (backlight_hundreds * 100);
    backlight_tens = temp / 10;
    backlight_ones = temp - (backlight_tens * 10);

    LCD_clear_row(4);

    LCD_write(LCD_COMMAND, LCD_YADDR(4));
    LCD_write(LCD_COMMAND, LCD_XADDR(10));
    
    if(backlight_seconds == 255)
    {
        LCD_string("Always On");
    }
    else if(backlight_seconds == 0)
    {
        LCD_string("Always Off");
    }
    else
    {
        LCD_char(backlight_hundreds+48);
        LCD_char(backlight_tens+48);
        LCD_char(backlight_ones+48);
    }

    return;
}



void LCD_tempco_menu(void)
{

    LCD_write(LCD_COMMAND, LCD_YADDR(1));
    LCD_write(LCD_COMMAND, LCD_XADDR(0));
    LCD_string("LCD Temp Coeff");

    LCD_write(LCD_COMMAND, LCD_YADDR(3));
    LCD_write(LCD_COMMAND, LCD_XADDR(4));

    LCD_char(LCD_tempco + 48);


    //If either of these buttons are pressed, exit
    //  out of this loop, back to the main loop.
    //There, if TIME_SET_SW has been pressed, then
    //  that main loop will also exit
    while(TIME_SET_SW && START_SET_SW)
    {

        if(LCD_tempco == 4)
        {
            LCD_tempco = 3;
        }

                if(!SW_P)
                {
                    milliseconds(DEBOUNCE_TIME);
                    while(!SW_P);
                    LCD_tempco++;

                    LCD_write(LCD_COMMAND, LCD_YADDR(3));
                    LCD_write(LCD_COMMAND, LCD_XADDR(4));
                    LCD_char(LCD_tempco + 48);
                }

                if(!SW_M)
                {
                    milliseconds(DEBOUNCE_TIME);
                    while(!SW_M);
                    if(LCD_tempco!=0)
                    {
                        LCD_tempco--;
                    }

                    LCD_write(LCD_COMMAND, LCD_YADDR(3));
                    LCD_write(LCD_COMMAND, LCD_XADDR(4));
                    LCD_char(LCD_tempco + 48);
                }

                //When the manual switch is pressed, then write the
                // desired data to the LCD
                if(!MANUAL_SW)
                {
                    milliseconds(DEBOUNCE_TIME);   //Debounce the switch
                    while(!MANUAL_SW);  //Wait until the button is realeased


                    LCD_write(LCD_COMMAND, 0x21);   //Tell the LCD that extended commands follow
                    milliseconds(5);

                    LCD_write(LCD_COMMAND, ((LCD_tempco & 0x03) | 0x04));

                    milliseconds(5);
                    LCD_write(LCD_COMMAND, 0x20);   //Tell the LCD that regular commands follow
                                                    //  Set this back to normal
                    milliseconds(5);

                    EEPROM_write_with_check(LCD_TEMPCO_ADDR, LCD_tempco);

                }

    }

    while(!START_SET_SW);   //If this button was pressed, then wait for it to be released

    state++;        //move to the next state

    return;
}


void Filter_minutes_display(void)
{

    LCD_write(LCD_COMMAND, LCD_YADDR(2));
    LCD_write(LCD_COMMAND, LCD_XADDR(0));
    LCD_string("Filter Minutes");

    LCD_write(LCD_COMMAND, LCD_YADDR(3));
    LCD_write(LCD_COMMAND, LCD_XADDR(0));
    LCD_string("Count:");

    display_filter_minutes();


    //If either of these buttons are pressed, exit
    //  out of this loop, back to the main loop.
    //There, if TIME_SET_SW has been pressed, then
    //  that main loop will also exit
    while(TIME_SET_SW && START_SET_SW)
    {
                if(!SW_P)
                {
                    milliseconds(DEBOUNCE_TIME);
                    while(!SW_P);
                    filter_minutes_count++;

                    display_filter_minutes();
                }

                if(!SW_M)
                {
                    milliseconds(DEBOUNCE_TIME);
                    while(!SW_M);
                    filter_minutes_count--;

                    display_filter_minutes();
                }

                //When the manual switch is pressed, then write the
                // desired data to the EEPROM
                if(!MANUAL_SW)
                {
                    /* Write the low byte of the filter count minutes to EEPROM */
                    EEPROM_write_with_check(FILTER_MINUTES_COUNT_L, (filter_minutes_count & 0xFF));

                    /* Shift the filter count minutes by 8, and then write the high byte
                       of filter count minutes to EEPROM */
                    EEPROM_write_with_check(FILTER_MINUTES_COUNT_H, ((filter_minutes_count >> 8) & 0xFF));

                    //After the EEPROM value is written, just double check that the values
                    //  were written to what you expect
                    EEPROM_value_check(FILTER_MINUTES_COUNT_L, (filter_minutes_count & 0xFF));
                    EEPROM_value_check(FILTER_MINUTES_COUNT_H, ((filter_minutes_count >> 8) & 0xFF));


                }

    }

    while(!START_SET_SW);   //If this button was pressed, then wait for it to be released

    state++;        //move to the next state

    return;
}


void display_filter_minutes(void)
{
    unsigned char temp = 0;
    unsigned char temp2 = 0;

    filter_minutes_thousands = filter_minutes_count / 1000;
    temp = filter_minutes_count - (filter_minutes_thousands * 1000);
    filter_minutes_hundreds = temp / 100;
    temp2 = filter_minutes_count - (filter_minutes_hundreds * 100);
    filter_minutes_tens = temp / 10;
    filter_minutes_ones = temp - (filter_minutes_tens * 10);

    LCD_clear_row(4);

    LCD_write(LCD_COMMAND, LCD_YADDR(4));
    LCD_write(LCD_COMMAND, LCD_XADDR(28));

    LCD_char(filter_minutes_thousands+48);
    LCD_char(filter_minutes_hundreds+48);
    LCD_char(filter_minutes_tens+48);
    LCD_char(filter_minutes_ones+48);

    return;
}